/* eslint-disable @typescript-eslint/no-unused-expressions */
/**
 * 禁止更新lodop版本
 *
 */
import { App } from 'antd';
import { useEffect, useState } from 'react';

/* eslint-disable @typescript-eslint/no-explicit-any */
const MainJS = 'CLodopfuncs.js',
  URL_WS1 = 'ws://localhost:8000/' + MainJS, //ws用8000/18000
  URL_WS2 = 'ws://localhost:18000/' + MainJS,
  URL_HTTP1 = 'http://localhost:8000/' + MainJS, //http用8000/18000
  URL_HTTP2 = 'http://localhost:18000/' + MainJS,
  URL_HTTP3 = 'https://localhost.lodop.net:8443/' + MainJS; //https用8000/8443

let CreatedOKLodopObject: any;
let CLodopIsLocal: any;
let LoadJsState: string;
let LODOP: any;

let timer: any;

const strFontTag = '<br><font>打印控件';
const strLodopInstall =
  strFontTag +
  "未安装!点击这里<a href='install_lodop32.exe' target='_self'>执行安装</a>";
const strLodopUpdate =
  strFontTag +
  "需要升级!点击这里<a href='install_lodop32.exe' target='_self'>执行升级</a>";
const strLodop64Install =
  strFontTag +
  "未安装!点击这里<a href='install_lodop64.exe' target='_self'>执行安装</a>";
const strLodop64Update =
  strFontTag +
  "需要升级!点击这里<a href='install_lodop64.exe' target='_self'>执行升级</a>";
const strCLodopInstallA =
  "<br><font >Web打印服务未安装启动，点击这里<a href='/CLodop_Setup_for_Win32NT.exe' target='_self'>下载执行安装</a>";
const strCLodopInstallB =
  "<br>（若此前已安装过，可<a href='CLodop.protocol:setup' target='_self'>点这里直接再次启动</a>）";
const strCLodopUpdate =
  "<br><font >Web打印服务CLodop需升级!点击这里<a href='/CLodop_Setup_for_Win32NT.exe' target='_self'>执行升级</a>";
const strLodop7FontTag = '<br><font>Web打印服务Lodop7';
const strLodop7HrefX86 =
  "点击这里<a href='Lodop7_Linux_X86_64.tar.gz' target='_self'>下载安装</a>(下载后解压，点击lodop文件开始执行)";
const strLodop7HrefARM =
  "点击这里<a href='Lodop7_Linux_ARM64.tar.gz'  target='_self'>下载安装</a>(下载后解压，点击lodop文件开始执行)";
const strLodop7Install_X86 =
  strLodop7FontTag + '未安装启动，' + strLodop7HrefX86;
const strLodop7Install_ARM =
  strLodop7FontTag + '未安装启动，' + strLodop7HrefARM;
const strLodop7Update_X86 = strLodop7FontTag + '需升级，' + strLodop7HrefX86;
const strLodop7Update_ARM = strLodop7FontTag + '需升级，' + strLodop7HrefARM;
const strInstallOK = '，成功后请刷新本页面或重启浏览器。</font>';

const isWinIE =
  /MSIE/i.test(navigator.userAgent) || /Trident/i.test(navigator.userAgent);
const isWinIE64 = isWinIE && /x64/i.test(navigator.userAgent);
const isLinuxX86 =
  /Linux/i.test(navigator.platform) && /x86/i.test(navigator.platform);
const isLinuxARM =
  /Linux/i.test(navigator.platform) && /aarch/i.test(navigator.platform);

/** 判断是否需要CLodop(那些不支持插件的浏览器) */
const needCLodop = () => {
  try {
    const ua = navigator.userAgent;
    if (
      ua.match(/Windows\sPhone/i) ||
      ua.match(/iPhone|iPod|iPad/i) ||
      ua.match(/Android/i) ||
      ua.match(/Edge\D?\d+/i)
    )
      return true;
    const verTrident = ua.match(/Trident\D?\d+/i);
    const verIE = ua.match(/MSIE\D?\d+/i);
    let verOPR: any = ua.match(/OPR\D?\d+/i);
    let verFF: any = ua.match(/Firefox\D?\d+/i);
    const x64 = ua.match(/x64/i);
    if (!verTrident && !verIE && x64) return true;
    else if (verFF) {
      verFF = verFF[0].match(/\d+/);
      if (verFF[0] >= 41 || x64) return true;
    } else if (verOPR) {
      verOPR = verOPR[0].match(/\d+/);
      if (verOPR[0] >= 32) return true;
    } else if (!verTrident && !verIE) {
      let verChrome: any = ua.match(/Chrome\D?\d+/i);
      if (verChrome) {
        verChrome = verChrome[0].match(/\d+/);
        if (verChrome[0] >= 41) return true;
      }
    }
    return false;
  } catch {
    return true;
  }
};

/**
 * 检查加载成功与否，如没成功则用http(s)再试
 * 低版本CLODOP6.561/Lodop7.043及前)用本方法
 * 注意：安全策略
 * 插入外部脚本
 * @returns
 *
 */
const checkOrTryHttp = () => {
  if ((window as any).getCLodop) {
    LoadJsState = 'complete';
    return true;
  }
  // TODO 未处理 本页由【试用版打印控件Lodop6.6.1.1】输出
  if (LoadJsState == 'loadingB' || LoadJsState == 'complete') return;

  LoadJsState = 'loadingB';

  fetch(URL_HTTP1)
    .then((res) => {
      return res.text();
    })
    .then((text) => {
      if (!(window as any).getCLodop) {
        LoadJsState = 'complete';
        const jsStr =
          text?.replace(
            'strData=strData+"browseurl="+window.location.href+this.DelimChar;',
            'strData=strData+"browseurl="+"http://localhost:8080/";',
          ) || text;
        eval(jsStr);
        return true;
      }
    })
    .catch(() => {
      return fetch(URL_HTTP2);
    })
    .then((res: any) => {
      return res.text();
    })
    .then((text) => {
      if (!(window as any).getCLodop) {
        LoadJsState = 'complete';
        const jsStr =
          text?.replace(
            'strData=strData+"browseurl="+window.location.href+this.DelimChar;',
            'strData=strData+"browseurl="+"http://localhost:8080/";',
          ) || text;
        eval(jsStr);
        return true;
      }
    })
    .catch(() => {
      LoadJsState = 'complete';
    });
};

//==加载Lodop对象的主过程:==
(function loadCLodop() {
  if (!needCLodop()) return;
  CLodopIsLocal = !!(URL_WS1 + URL_WS2).match(/\/\/localho|\/\/127.0.0./i);
  LoadJsState = 'loadingA';
  if (!window.WebSocket && (window as any).MozWebSocket)
    window.WebSocket = (window as any).MozWebSocket;
  //ws方式速度快(小于200ms)且可避免CORS错误,但要求Lodop版本足够新:
  try {
    const WSK1 = new WebSocket(URL_WS1);
    WSK1.onopen = function () {
      setTimeout(checkOrTryHttp, 200);
    };
    WSK1.onmessage = function (e) {
      if (!(window as any).getCLodop) {
        // INFO 临时处理 本页由【试用版打印控件Lodop6.6.1.1】输出
        const jsStr =
          e.data?.replace(
            'strData=strData+"browseurl="+window.location.href+this.DelimChar;',
            'strData=strData+"browseurl="+"http://localhost:8080/";',
          ) || e.data;
        eval(jsStr);
      }
    };
    WSK1.onerror = function () {
      const WSK2 = new WebSocket(URL_WS2);
      WSK2.onopen = function () {
        setTimeout(checkOrTryHttp, 200);
      };
      WSK2.onmessage = function (e) {
        if (!(window as any).getCLodop) {
          // INFO 临时处理 本页由【试用版打印控件Lodop6.6.1.1】输出
          const jsStr =
            e.data?.replace(
              'strData=strData+"browseurl="+window.location.href+this.DelimChar;',
              'strData=strData+"browseurl="+"http://localhost:8080/";',
            ) || e.data;
          eval(jsStr);
        }
      };
      WSK2.onerror = function () {
        checkOrTryHttp();
      };
    };
  } catch {
    checkOrTryHttp();
  }
})();

const useLodop = () => {
  const { message, modal } = App.useApp();
  /** lodop 总对象 */
  const [lodop, setLodop] = useState<any>();

  /** 打印机数量 */
  const [printCount, setPrintCount] = useState(0);

  /** 打印机列表 */
  const [printerList, setPrinterList] = useState<
    { label: string; value: number }[]
  >([]);

  /** 获取控件对象 */
  const getLodop = () => {
    return new Promise((resolve, reject) => {
      if (LODOP) {
        resolve(LODOP);
        return;
      }

      const t = setInterval(() => {
        if (LoadJsState === 'loadingA' || LoadJsState === 'loadingB') {
          // message.warning('打印控件加载中，请稍等一下再操作.');
          console.log('打印控件加载中，请稍等一下再操作.: ');
          return;
        }
        if (LoadJsState === 'complete' && (window as any).getCLodop) {
          try {
            LODOP = (window as any)?.getCLodop?.();

            LODOP.PRINT_INIT();
            //===如下空白位置适合调用统一功能(如注册语句、语言选择等):=======================
            // TODO 注册码
            LODOP.SET_LICENSES(
              '',
              'EE0887D00FCC7D29375A695F728489A6',
              'C94CEE276DB2187AE6B65D56B3FC2848',
              '',
            );
            resolve(LODOP);
            clearInterval(t);
            return;
          } catch (error) {
            console.error('error: ', error);
            reject('获取打印控件失败');
            clearInterval(t);
            return;
          }
        } else {
          console.error('获取打印控件失败: ');
          reject('获取打印控件失败');
          clearInterval(t);
          return;
        }
      }, 1000);
    });
  };

  /** 获取打印机基础信息 */
  const getPrinterInfo = (lodop: any) => {
    if (!lodop) return;

    const printerCount = lodop.GET_PRINTER_COUNT();

    const printers = [];

    for (let i = 0; i < printerCount; i++) {
      const printerName = lodop.GET_PRINTER_NAME(i);
      printers.push({
        label: printerName,
        value: i,
      });
    }

    setPrintCount(printerCount);
    setPrinterList(printers);
  };

  /** 打印前的检查 */
  const beforePrint = () => {
    if (LoadJsState === 'loadingA' || LoadJsState === 'loadingB') {
      message.warning('打印控件加载中，请稍等一下再操作.');
      return false;
    }
    // if (!LODOP && LoadJsState === 'complete') {
    //   message.warning('lodop 正在初始化，请稍等一下再操作.');
    //   return false;
    // }

    let strAlertMessage;
    if (!LODOP) {
      if (isLinuxX86) {
        strAlertMessage = strLodop7Install_X86;
      } else if (isLinuxARM) {
        strAlertMessage = strLodop7Install_ARM;
      } else {
        strAlertMessage =
          strCLodopInstallA + (CLodopIsLocal ? strCLodopInstallB : '');
      }
      modal.confirm({
        title: '打印控件异常',
        content: (
          <div
            dangerouslySetInnerHTML={{
              __html: strAlertMessage + strInstallOK,
            }}
          ></div>
        ),
      });
      return false;
    } else {
      if (isLinuxX86 && LODOP.CVERSION < '7.0.7.5')
        strAlertMessage = strLodop7Update_X86;
      else if (isLinuxARM && LODOP.CVERSION < '7.0.7.5')
        strAlertMessage = strLodop7Update_ARM;
      else if ((window as any).CLODOP.CVERSION < '6.6.0.9')
        strAlertMessage = strCLodopUpdate;

      if (strAlertMessage) {
        modal.confirm({
          title: '打印控件版本异常',
          content: (
            <div
              dangerouslySetInnerHTML={{
                __html: strAlertMessage + strInstallOK,
              }}
            ></div>
          ),
        });
        return false;
      }
    }
    return true;
  };

  /** 打印 */
  const print = async ({
    top = '0',
    left = '0',
    width,
    height,
    printContent,
    index,
    direction,
    scale,
    printPages,
    marginTop,
    marginLeft,
    marginRight,
    marginBottom,
    lodopPreview,
    times,
  }: {
    top?: string;
    left?: string;
    /** 纸张宽 */
    width: string;
    /** 纸张高 */
    height: string;
    /** 打印内容 html 字符串 行内样式，或者包含style标签 */
    printContent: string[];
    /** 打印机序号 */
    index: number;
    /** 1---纵(正)向打印，固定纸张；
     * 2---横向打印，固定纸张；
     * 3---纵(正)向打印，宽度固定，高度按打印内容的高度自适应；
     * 0(或其它)----打印方向由操作者自行选择或按打印机缺省设置；
     *  */
    direction: 0 | 1 | 2 | 3;
    /** 缩放比例 % */
    scale: number;
    /** 设置打印页数 */
    printPages?: string;
    /** 当前页打印次数 */
    times: number;
    marginTop: number;
    marginLeft: number;
    marginRight: number;
    marginBottom: number;
    lodopPreview?: boolean;
  }) => {
    const loaded = beforePrint();

    console.log('loaded: ', loaded);

    if (!loaded) return false;

    message.info('正在唤起打印，请稍等...');

    lodop.PRINT_INIT();
    // 打印位置 以及打印内容
    // lodop.ADD_PRINT_HTM(top, left, width, height, printContent);

    // 打印状态捕获
    lodop.SET_PRINT_MODE('CATCH_PRINT_STATUS', true);

    lodop.On_Return = function (taskID: string, value: string) {
      const t = setInterval(() => {
        lodop.GET_VALUE('PRINT_STATUS_TEXT', value);
        lodop.On_Return = function (taskID: string, value: string) {
          message.info(value);
        };
        lodop.GET_VALUE('PRINT_STATUS_OK', value);
        lodop.On_Return = function (taskID: string, value: string) {
          message.info(value);
          clearInterval(t);
        };
      }, 500);
    };

    // 选择打印机
    lodop.SET_PRINTER_INDEX(index);

    // 选择打印方向以及纸张大小
    lodop.SET_PRINT_PAGESIZE(direction, width, height);

    // 设置打印边距
    lodop.SET_PRINT_STYLE('marginTop', marginTop + 'mm');
    lodop.SET_PRINT_STYLE('marginLeft', marginLeft + 'mm');
    lodop.SET_PRINT_STYLE('marginRight', marginRight + 'mm');
    lodop.SET_PRINT_STYLE('marginBottom', marginBottom + 'mm');

    // 设置缩放
    lodop.SET_PRINT_MODE('PRINT_PAGE_PERCENT', scale + '%');

    for (let i = 0; i < printContent.length; i++) {
      const content = printContent[i];
      // 打印位置 以及打印内容
      lodop.NEWPAGE();
      lodop.ADD_PRINT_HTM(top, left, width, height, content);

      // 打印页
      printPages && lodop.SET_PRINT_MODE('PRINT_NOCOLLATE', printPages);
    }

    if (lodopPreview) {
      lodop.PREVIEW();
    } else {
      // TODO 数量过大需要进行分批处理
      // 按 printPages 顺序打印
      if (times) {
        for (let i = 0; i < times; i++) {
          lodop.PRINT();
        }
      }
    }
    return true;
  };

  useEffect(() => {
    if (timer) clearTimeout(timer);
    timer = setTimeout(async () => {
      const l = await getLodop();
      setLodop(l);
      getPrinterInfo(l);
    });
  }, []);

  return {
    lodop,
    printCount,
    printerList,
    print,
  };
};

export default useLodop;
